#ifndef _CTRIANGLEMESH_H_
#define _CTRIANGLEMESH_H_

#include "StdDefs.h"
#include "CMathFixed.h"
#include "CVector3d.h"
#include "CTriangle3d.h"

#include "CCapsule3d.h"
#include "CSphere.h"
#include "CTriangle3d.h"

class CFace
{
public:
    int					m_idx[3];
};


class CTriangleMesh
{
public:
	CTriangleMesh();
	CTriangleMesh( CTriangle3d* triangles, int numTriangles );
	CTriangleMesh( CVector3d* vertices, int numVertices, int* idx, int numIndices );
	~CTriangleMesh();

	boolean					Sweep( const CSphere& sphere, const CVector3d& v1, const CVector3d& v2, fixed& t, int &faceIdx ) const;
	boolean					Sweep( const CVector3d& pos, fixed radius, const CVector3d& v1, const CVector3d& v2, fixed &t, int &faceIdx ) const;

	boolean					Sweep( const CCapsule3d& capsule, const CVector3d& v1, const CVector3d& v2, fixed& t ) const;
	boolean					Sweep( const CVector3d& segA, const CVector3d& segB, fixed radius, const CVector3d& v1, const CVector3d& v2, fixed &t, int &faceIdx ) const;
	
	boolean					Intersects( const CSphere& sphere, int &faceIdx ) const;
	boolean					Intersects( const CVector3d& pos, const fixed radius, int &faceIdx ) const;

	boolean					Intersects( const CCapsule3d& capsule, int &faceIdx ) const;
	boolean					Intersects( const CVector3d& segA, const CVector3d& segB, fixed radius, int &faceIdx ) const;

	boolean					Intersects( const CTriangle3d& t, int &faceIdx ) const;
	boolean					Intersects( const CVector3d& tv0, const CVector3d& tv1, const CVector3d& tv2, int &faceIdx ) const;

	boolean					Intersects( const CPlane& plane, int &faceIdx ) const;

	boolean					IsMeshConvex() const;					

	void					Create( CVector3d* vertices, int numVertices, int* idx, int numIndices );
	
	void					SetNumVertices( int num, boolean keepPreviousVertices = FALSE );
	int						GetNumVertices() const;
	const CVector3d&		GetVertex( int index ) const;
	CVector3d&				GetVertex( int index );
	void					RemoveRedundantVertices();


	void					SetNumFaces( int num, boolean keepPreviousFaces = FALSE );
	int						GetNumFaces() const;
	const CFace&			GetFace( int index ) const;
	CFace&					GetFace( int index );

	const CVector3d&		GetFaceVertex( int faceIndex, int vIndex ) const;
	CVector3d&				GetFaceVertex( int faceIndex, int vIndex );

protected:
	void					Init(); // Initializes the mesh object. The mesh counts are set to 0 and its pointers are set to NULL. Note: This method is not intended to be called by developers. It is used internally.

	int						m_numVertices;
	int						m_numFaces;
	CVector3d*				m_vertices;
	CFace*					m_faces;
};


inline
int	CTriangleMesh::GetNumVertices() const
{
	return m_numVertices;
}


inline
const CVector3d& CTriangleMesh::GetVertex( int index ) const
{
	ASSERT ( index < GetNumVertices() );
	return m_vertices[ index ];
}

inline
CVector3d& CTriangleMesh::GetVertex( int index )
{
	ASSERT ( index < GetNumVertices() );
	return m_vertices[ index ];
}


inline
int	CTriangleMesh::GetNumFaces() const
{
	return m_numFaces;
}



inline
const CFace& CTriangleMesh::GetFace( int index ) const
{
	ASSERT ( index < GetNumFaces() );
	return m_faces[ index ];
}


inline
CFace& CTriangleMesh::GetFace( int index )
{
	ASSERT ( index < GetNumFaces() );
	return m_faces[ index ];
}


inline
const CVector3d& CTriangleMesh::GetFaceVertex( int faceIndex, int vIndex ) const
{
	const CFace& face = GetFace( faceIndex );
	ASSERT ( vIndex < 3 );
	return GetVertex( face.m_idx[vIndex] );
}


inline
CVector3d& CTriangleMesh::GetFaceVertex( int faceIndex, int vIndex )
{
	const CFace& face = GetFace( faceIndex );
	ASSERT ( vIndex < 3 );
	return GetVertex( face.m_idx[vIndex] );
}




#endif //_CTRIANGLEMESH_H_